package com.smh;

import com.smh.interfaces.Queue;
import org.junit.jupiter.api.Test;

import java.util.Iterator;

/**
 * @author shiminghui
 * @date 2025/2/10 10:48
 * @description: TODO
 */
public class _014_队列_环形数组 {

    @Test
    public void test1() {
        Queue<Integer> queue = new MyQueue<Integer>(1);
        queue.offer(1);
        queue.offer(2);
        Integer poll = queue.poll();
        System.out.println(poll);
        Integer poll1 = queue.poll();
        System.out.println(poll1);

    }


    private static class MyQueue<T> implements Queue<T>, Iterable<T> {
        // 也可以专门用一个空间存储tail指针，即队列容量为capacity-1，满的条件为（tail+1）%capacity==head

        private final int capacity;
        private final T[] data;
        // 也可以两个数递增，索引随用随计算，判断空为head==tail，判断满为head==tail-data.length
        private int head;
        private int tail;
        private int size;

        public MyQueue() {
            this(10);
        }

        @SuppressWarnings("unchecked")
        public MyQueue(int capacity) {
            this.capacity = capacity;
            this.data = (T[]) new Object[capacity];
            this.head = 0;
            this.tail = 0;
            this.size = 0;
        }

        @Override
        public boolean offer(T value) {
            if (isFull()) {
                return false;
            }
            data[tail++] = value;
            tail = tail % capacity;
            size++;
            return true;
        }

        @Override
        public T poll() {
            if (isEmpty()) {
                return null;
            }
            T value = data[head++];
            head = head % capacity;
            size--;
            return value;
        }

        @Override
        public T peek() {
            if (isEmpty()) {
                return null;
            }
            return data[head];
        }

        @Override
        public boolean isEmpty() {
            return size == 0;
        }

        @Override
        public boolean isFull() {
            return size >= capacity;
        }

        @Override
        public Iterator<T> iterator() {
            return new Iterator<T>() {
                private int index = head;
                private int count = size;

                @Override
                public boolean hasNext() {
                    return count != 0;
                }

                @Override
                public T next() {
                    T value = data[index++];
                    index = index % capacity;
                    count--;
                    return value;
                }
            };
        }
    }
}
